perm filename REINIT.TEX[CLS,LSP] blob sn#856505 filedate 1988-04-27 generic text, type T, neo UTF8
Throughout Chapter 2, change INITIALIZE-INSTANCE to
INITIALIZE-NEW-INSTANCE.

Throughout Chapter 2, change  UPDATE-INSTANCE-STRUCTURE to
UPDATE-INSTANCE-FOR-REDEFINED-CLASS.

Throughout Chapter 2, change  CLASS-CHANGED to
UPDATE-INSTANCE-FOR-DIFFERENT-CLASS.

Page 2-6:  "Tools used for simple object-oriented programming":  include
INITIALIZE-NEW-INSTANCE, INITIALIZE-INSTANCE.

Page 2-6:  "Functions Underlying...":  include
UPDATE-INSTANCE-FOR-REDEFINED-CLASS, 
UPDATE-INSTANCE-FOR-DIFFERENT-CLASS, REINITIALIZE-INSTANCE

Page 2-16:   add &rest initargs to the lambda-list of this method:

(defmethod update-instance-for-different-class ((old x-y-position) 
                                                (new rho-theta-position)
	                                        &rest initargs)
  ;; Copy the position information from old to new to make new
  ;; be a rho-theta-position at the same position as old.
  (let ((x (slot-value old 'x))
        (y (slot-value old 'y)))
    (setf (slot-value new 'rho) (sqrt (+ (* x x) (* y y)))
          (slot-value new 'theta) (atan y x))))


----------------------------
There are five new or revised function descriptions below:

initialize-instance is a new function description
reinitialize-instance is a new function description

initialize-new-instance replaces the old initialize-instance
update-instance-for-different-class replaces the old class-changed
update-instance-for-redefined-class replaces the old update-instance-structure


----------------------------

\begincom{initialize-instance}\ftype{Standard Generic Function}

\label Purpose:

The generic function {\bf initialize-instance} is called in several
contexts to initialize, reinitialize, or update an instance.   It is
called by {\bf initialize-new-instance}, {\bf reinitialize-instance},
{\bf update-instance-for-redefined-class}, and {\bf
update-instance-for-different-class}.    This generic function performs
the initialization work that is sharable among all of those contexts.

The function {\bf initialize-instance} is called with an instance, a
list of slots to initialize according to their initforms, and 
initialization arguments.

The system-supplied primary method on {\bf initialize-instance}
initializes the slots with values according to the initialization
arguments and any initforms for the slots.    The second argument
indicates which slots should be initialized according to their
initforms:  it is either a list of names of slots, or {\bf t}
(indicating all slots), or {\bf nil} (indicating no slots).   The second
argument does not affect any initialization done by initialization
arguments.

The system-supplied primary method behaves as follows, regardless of
whether the slots are local or shared: 

\beginlist

\item{\bull} For any slot for which a corresponding initialization
argument was provided in the call to {\bf initialize-instance}, the
value of the initialization argument is stored into the slot.  This
happens even if a value has already been stored in the slot before the
method is run.

\item{\bull} Any slots indicated by the second argument that are still
unbound at this point are initialized according to their initforms.  For
any such slot that has an {\bf :initform} form, that form is evaluated
in the lexical environment of its defining {\bf defclass} form and the
result is stored into the slot.   This does not happen if a value has
already been stored in the slot by an initialization argument, or
before the method is run.  For example, if a {\bf :before} method stores
a value in the slot, the {\bf :initform} form will not be used to supply
a value for the slot.

\item{\bull} The rules mentioned in the section ``Rules for Duplicate
Initialization Arguments'' are obeyed.

\endlist

\label Syntax:

\Defgen {initialize-instance} {instance slots-for-initform {\tt \&rest {\it initargs}}}

\label Method Signatures:

\Defmeth {initialize-instance} {({\it instance\/} standard-object) {\it
slots-for-initform\/} {\rest} {\it initargs}} 

\label Arguments:

The {\it instance\/} argument is the object to be initialized.

The {\it slots-for-initform\/} argument indicates which slots should be
initialized according to their initforms.  It is either a list of names
of slots, or {\bf t} (indicating all slots), or {\bf nil} (indicating no
slots).

The {\it initargs\/} argument consists of alternating initialization 
argument names and values.

\label Values:

The modified instance is returned as the result.

\label Remarks:

Initialization arguments are declared as valid by using the {\bf
:initarg} option to {\bf defclass}, or by defining methods for {\bf {\bf
initialize-instance}.  The keyword name of each keyword parameter
specifier in the lambda-list of any method defined on or {\bf
initialize-instance} is declared as a valid initialization argument
name for all classes for which that method is applicable.

Implementations are permitted to optimize {\bf :initform} forms that 
neither produce nor depend on side effects, by evaluating these forms
and storing them into slots before running any {\bf
initialize-new-instance} methods, rather than by handling them in the
primary {\bf initialize-new-instance} method.  (This optimization might
be implemented by having the {\bf allocate-instance} method copy a
prototype instance.)

Implementations are permitted to optimize default initial value forms
for initialization arguments associated with slots by not actually
creating the complete initialization argument list when the only method
that would receive the complete list is the method on {\bf
standard-object}.  In this case default initial value forms can be 
treated like {\bf :initform} forms.  This optimization has no visible
effects other than a performance improvement.

\label See Also:

``Object Creation and Initialization''

``Rules for Duplicate Initialization Arguments''

``Declaring the Validity of Initialization Arguments''

{\bf initialize-new-instance

reinitialize-instance

update-instance-for-redefined-class

update-instance-for-different-class

slot-boundp

slot-makunbound}

\endcom


\begincom{initialize-new-instance}\ftype{Standard Generic Function}

\label Purpose:

The generic function {\bf initialize-new-instance} is called by {\bf
make-instance} to initialize a newly-created instance.  The function
{\bf initialize-new-instance} is called with the new instance, and with
the defaulted initialization arguments.

The system-supplied primary method on {\bf initialize-new-instance}
checks the validity of initialization arguments, and signals an error if
an initialization argument is supplied that is not declared as valid.
This method then initializes the slots with values according to the
initialization arguments and to the initforms of the slots.   It does
this by calling the generic function {\bf initialize-instance} with
three arguments:  the instance, {\bf t} (this indicates that all slots
should be initialized according to their initforms), and the defaulted
initialization arguments.  

\label Syntax:

\Defgen {initialize-new-instance} {instance {\tt \&rest {\it initargs}}}

\label Method Signatures:

\Defmeth {initialize-new-instance} {({\it instance\/} standard-object) {\rest} {\it initargs}}

\label Arguments:

The {\it instance\/} argument is the object to be initialized.

The {\it initargs\/} argument consists of alternating initialization
argument names and values.

\label Values:

The modified instance is returned as the result.

\label Remarks:

Initialization arguments are declared as valid by using the {\bf
:initarg} option to {\bf defclass}, or by defining methods for {\bf
initialize-new-instance} or {\bf initialize-instance}.  The keyword name
of each keyword parameter specifier in the lambda-list of any method
defined on {\bf initialize-new-instance} or {\bf initialize-instance} is
declared as a valid initialization argument name for all classes for
which that method is applicable.

\label See Also:

``Object Creation and Initialization''

``Rules for Duplicate Initialization Arguments''

``Declaring the Validity of Initialization Arguments''

{\bf initialize-instance

make-instance

slot-boundp

slot-makunbound}

\endcom
\begincom{update-instance-for-different-class}\ftype{Standard Generic Function}

\label Purpose:

The generic function {\bf update-instance-for-different-class} is not
intended to be called by programmers.  Programmers are expected to write
methods for it.  The function {\bf update-instance-for-different-class}
is called only by the function {\bf change-class}.

The system-supplied primary method on {\bf
update-instance-for-different-class} checks the validity of
initialization arguments, and signals an error if an initialization
argument is supplied that is not declared as valid.  This method then
initializes slots with values according to the initialization arguments,
and initializes the newly-added slots with values according to their
initforms.  It does this by calling the generic function {\bf
initialize-instance} with three arguments:  the instance, a list of
names of the newly-added slots, and initialization arguments.  Here, a
``newly-added slot'' is a local slot defined by the current class where
there is no slot by the same name defined by the previous class.

Methods for {\bf update-instance-for-different-class} can be defined to
specify actions to be taken when an instance is updated.  If only {\bf
:after} methods for {\bf update-instance-for-different-class} are
defined, they will be run after the system-supplied primary method for
initialization and therefore will not interfere with the default
behavior of {\bf update-instance-for-different-class}.

\label Syntax:

\Defgen {update-instance-for-different-class} {previous current} {\tt \&rest {\it initargs}}}

\label Method Signatures:

\Defmeth {update-instance-for-different-class} {({\it previous\/}
standard-object) ({\it current\/} standard-object)} {\tt \&rest {\it initargs}}} 

\label Arguments:
The arguments to {\bf update-instance-for-different-class} are computed by {\bf
change-class}.  When {\bf change-class} is invoked on an instance, a
copy of that instance is made; {\bf change-class} then destructively
alters the original instance.  The first argument to {\bf
update-instance-for-different-class}, {\it previous\/}, is that copy; it holds the old slot
values temporarily.  This argument has dynamic extent within {\bf
change-class}; if it is referenced in any way once {\bf update-instance-for-different-class}
returns, the results are undefined.  The second argument to {\bf
update-instance-for-different-class}, {\it current}, is the altered original instance.

\vfill\eject
The intended use of {\it previous\/} is to extract old slot values by using
{\bf slot-value} or {\bf with-slots} or by invoking a reader generic
function, or to run other methods that were applicable to instances of
the original class.

The {\it initargs\/} argument consists of alternating initialization
argument names and values.

\label Values:

The value returned by {\bf update-instance-for-different-class} is
ignored by {\bf change-class}.

\label Examples:

See the example for the function {\bf change-class}.

\label Remarks:

Initialization arguments are declared as valid by using the {\bf
:initarg} option to {\bf defclass}, or by defining methods for {\bf
update-instance-for-different-class} or {\bf initialize-instance}.  The
keyword name of each keyword parameter specifier in the lambda-list of
any method defined on {\bf update-instance-for-different-class} or {\bf
initialize-instance} is declared as a valid initialization argument name
for all classes for which that method is applicable.

Methods on {\bf update-instance-for-different-class} can be defined to
initialize slots differently from {\bf change-class}.  The default
behavior of {\bf change-class} is described in ``Changing the Class of
an Instance.'' 


\label See Also:

``Changing the Class of an Instance''

``Rules for Duplicate Initialization Arguments''

``Declaring the Validity of Initialization Arguments''

{\bf change-class

initialize-instance}

\endcom


\begincom{update-instance-for-redefined-class}\ftype{Standard Generic Function}

\label Purpose:

The generic function {\bf update-instance-for-redefined-class} is not intended to
be called by programmers. Programmers are expected to write methods for it.
The generic function {\bf update-instance-for-redefined-class} is called
by the mechanism activated by {\bf make-instances-obsolete}.

The system-supplied primary method on {\bf 
update-instance-for-different-class} checks the validity of
initialization arguments, and signals an error if an initialization
argument is supplied that is not declared as valid.  This method then
initializes slots with values according to the initialization arguments,
and initializes the newly-added slots with values according to their
initforms.  It does this by calling the generic function {\bf
initialize-instance} with three arguments:  the instance, a list of
names of the newly-added slots, and initialization arguments.  Here, a
``newly-added slot'' is a local slot with no slot by the same name in 
the old version of the class. 

\label Syntax:

\Defgen {update-instance-for-redefined-class} {instance added-slots
discarded-slots property-list}  {\tt \&rest {\it initargs}}}

\label Method Signatures:

\Defmeth {update-instance-for-redefined-class} {\vtop{\hbox{({\it instance\/} standard-object)}
\hbox{\it added-slots discarded-slots property-list}}}
\hbox{\&rest {\it initargs}}

\label Arguments:

When {\bf make-instances-obsolete} is invoked or when a class has been
redefined and an instance is being updated, a property list is created
that captures the slot names and values of all the discarded slots with
values in the original instance.  The structure of the instance is
transformed so that it conforms to the current class definition.  The
arguments to {\bf update-instance-for-redefined-class} are this
transformed instance, a list of the names of the new slots added to the
instance, a list of the names of the old slots discarded from the
instance, and the property list containing the slot names and values for
slots that were discarded and had values.  Included in this list of
discarded slots are slots that were local in the old class and are
shared in the new class.

The {\it initargs\/} argument consists of alternating initialization
argument names and values.

\label Values:

The value returned by {\bf update-instance-for-redefined-class} is ignored.

\label Remarks:

Initialization arguments are declared as valid by using the {\bf
:initarg} option to {\bf defclass}, or by defining methods for {\bf
update-instance-for-redefined-class} or {\bf initialize-instance}.  The
keyword name of each keyword parameter specifier in the lambda-list of
any method defined on {\bf update-instance-for-redefined-class} or {\bf
initialize-instance} is declared as a valid initialization argument name
for all classes for which that method is applicable.


\vfill
\eject
\label Examples:

\screen!

(defclass position () ())

(defclass x-y-position (position)
    ((x :initform 0 :accessor position-x)
     (y :initform 0 :accessor position-y)))

;;; It turns out polar coordinates are used more than Cartesian 
;;; coordinates, so the representation is altered and some new
;;; accessor methods are added.

(defmethod update-instance-for-redefined-class
   ((pos x-y-position) added deleted plist &rest initargs)
  ;; Transform the x-y coordinates to polar coordinates
  ;; and store into the new slots.
  (let ((x (getf plist 'x))
        (y (getf plist 'y)))
    (setf (position-rho pos) (sqrt (+ (* x x) (* y y)))
          (position-theta pos) (atan y x))))

(defclass x-y-position (position)
    ((rho :initform 0 :accessor position-rho)
     (theta :initform 0 :accessor position-theta)))

;;; All instances of the old x-y-position class will be updated
;;; automatically.

;;; The new representation is given the look and feel of the old one.

(defmethod position-x ((pos x-y-position))  
   (with-slots (rho theta) pos (* rho (cos theta))))

(defmethod (setf position-x) (new-x (pos x-y-position))
   (with-slots (rho theta) pos
     (let ((y (position-y pos)))
       (setq rho (sqrt (+ (* new-x new-x) (* y y)))
             theta (atan y new-x))
       new-x)))

(defmethod position-y ((pos x-y-position))
   (with-slots (rho theta) pos (* rho (sin theta))))

(defmethod (setf position-y) (new-y (pos x-y-position))
   (with-slots (rho theta) pos
     (let ((x (position-x pos)))
       (setq rho (sqrt (+ (* x x) (* new-y new-y)))
             theta (atan new-y x))
       new-y)))

\endscreen!

\label See Also:

``Redefining Classes''

``Rules for Duplicate Initialization Arguments''

``Declaring the Validity of Initialization Arguments''

{\bf make-instances-obsolete

initialize-instance
}

\endcom


\begincom{reinitialize-instance}\ftype{Standard Generic Function}

\label Purpose:

The generic function {\bf reinitialize-instance} can be used to change
the values of local slots according to initialization arguments.  This
generic function is called by the Meta-Object Protocol.   It can also be
called by users.

The system-supplied primary method for {\bf reinitialize-instance}
checks the validity of initialization arguments, and signals an error if
an initialization argument is supplied that is not declared as valid.
The method then calls the generic function {\bf initialize-instance}
with three arguments:  the instance, {\bf nil} (which means no slots
should be initialized according to their initforms), and the
initialization arguments.

\label Syntax:

\Defgen {reinitialize-instance} {instance {\tt \&rest {\it initargs}}}

\label Method Signatures:

\Defmeth {reinitialize-instance} {({\it instance\/} standard-object) {\rest} {\it initargs}} 

\label Arguments:

The {\it instance\/} argument is the object to be initialized.

The {\it initargs\/} argument consists of alternating initialization
argument names and values.

\label Values:

The modified instance is returned as the result.

\label Remarks:

Initialization arguments are declared as valid by using the {\bf
:initarg} option to {\bf defclass}, or by defining methods for {\bf
reinitialize-instance} or {\bf initialize-instance}.  The keyword name
of each keyword parameter specifier in the lambda-list of any method
defined on {\bf reinitialize-instance} or {\bf initialize-instance} is
declared as a valid initialization argument name for all classes for
which that method is applicable.

\label See Also:

``Reinitializing an Instance''

``Rules for Duplicate Initialization Arguments''

``Declaring the Validity of Initialization Arguments''

{\bf initialize-new-instance

reinitialize-instance

update-instance-for-redefined-class

update-instance-for-different-class

slot-boundp

slot-makunbound}

\endcom